#pragma once

#include "View.h"

#define FLUID_GRID_SIZE_X 128
#define FLUID_GRID_SIZE_Y 128

#define FLUID_PROPERTY_ARRAY_SIZE ((FLUID_GRID_SIZE_X + 2) * (FLUID_GRID_SIZE_Y + 2))

namespace mgfx
{
	typedef int TextureID;
	typedef int ShaderID;
	typedef int VertexBufferID;
	typedef int IndexBufferID;
}

namespace mgui
{
	class TextField;
	class OnOffButton;
	class PushButton;
	struct EventArgs;
}

namespace mfluid
{
	class FluidView : public mcore::View
	{
	public:
		FluidView() { mName = "Fluid view"; }
		virtual ~FluidView()
		{
		}

		void init();
		void reset();
		virtual void unload();
		virtual void update(float dt);
		virtual void draw();

		virtual bool onWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam);

	private:
		void blow();

		void initGui();

		void updateTextures();
		void createSpriteBuffers();
		void drawVelocity();

		mgfx::TextureID mFluidDensityTex;

		float * mFluidDensity;
		float * mFluidDensityPrev;
		float * mFluidVelX;
		float * mFluidVelY;
		float * mFluidVelXPrev;
		float * mFluidVelYPrev;

		mgfx::VertexBufferID mSpriteVertexBuffer;
		mgfx::IndexBufferID mSpriteIndexBuffer;

		mgfx::ShaderID mShaderFluid;
		mgfx::ShaderID mShaderSprite;
		mgfx::TextureID mArrowTex;

		int mPrevMousePosX, mPrevMousePosY;

		mgui::TextField * mTextFieldDiffuseStrength;
		mgui::TextField * mTextFieldSourceStrength;
		mgui::TextField * mTextFieldProjIter;

		void textFieldDiffuseStrChanged(const mgui::EventArgs & args);
		void textFieldSourceStrChanged(const mgui::EventArgs & args);
		void buttonDrawVelSwitched(const mgui::EventArgs & args);
		void buttonSetDiffuseDensity(const mgui::EventArgs & args);
		void buttonSetProjIter(const mgui::EventArgs & args);
		void buttonReset(const mgui::EventArgs & args);
		void buttonBlow(const mgui::EventArgs & args);

		float mDiffuseStrength;
		float mSourceStrength;

		bool mDrawVelocity;

	};
}